#ifndef _EVENT_H_INCLUDED_
#define _EVENT_H_INCLUDED_
#include <functional>
#include <mutex>
#include <list>
#include <iostream>
const int DEFAULT_EVENT_POOL_SIZE = 1000;
//使用void*和std::function实现多态的事件定义
void defaultHandler(){
    std::cout << "This is a default handler" << std::endl;
}

struct event_t{
    /*
    type指明了事件类型
    -1：未分配事件
    0： 已分配事件
    1： 读就绪
    2:  写就绪
    3： 定时器事件
    */
    int type = -1;

    /*
    isReady指明了事件是否就绪
    */
    bool isReady = false;

    /*
    handler是事件就绪时的处理函数
    */
    std::function<void()> handler;

    /*
    reclaimer是事件被回收时的处理函数
    */
    std::function<void()> reclaimer;

    /*
    data是指向事件数据的指针
    */
    void* data = nullptr;

    /*
    isExpired指示事件是否过期
    */
    bool isExpired = false;

    inline void setDefaultEvent(){
        type = -1;
        handler =  defaultHandler;
        reclaimer = defaultHandler;
        data = nullptr;
        isExpired = false;
        isReady = false;
    }

};


//线程安全的事件池
class eventPool
{
private:
    using it_t = std::list<event_t>::iterator;
    std::list<event_t> events;
    std::mutex evPoolMutex;
    int numsAvailable;
public:
    inline eventPool():
    events(DEFAULT_EVENT_POOL_SIZE), numsAvailable(DEFAULT_EVENT_POOL_SIZE),evPoolMutex(){}

    inline event_t* getEvent()//从事件池获取一个空事件
    {
        if(numsAvailable == 0){
            events.push_back(event_t());
            numsAvailable++;
        }
        for(it_t it = events.begin(); it != events.end(); it++){
            if(it->type == -1){
                std::lock_guard<std::mutex> lock(evPoolMutex);
                if(it->type != -1){
                    continue;
                }
                else{
                    it->type = 0;
                    numsAvailable--;
                    return (event_t*)&(*it);
                }
            }
        }
    }

    
    //to do: 回收handler
    inline void returnEvent(event_t* theEvent)//向事件池归还事件
    {
        if(theEvent->type > 0){
            try
            {
              theEvent->reclaimer(); //调用回收函数
            }
            catch(const std::bad_function_call& e)
            {
                std::cerr << e.what() << '\n';
            }      
            
        }
        std::lock_guard<std::mutex> lock(evPoolMutex);
        theEvent->setDefaultEvent();
        numsAvailable++;
    } 
};


#endif